﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using SFast.DB.Page;
using System.ComponentModel;
using System.Collections;


namespace SFast.DB
{
    #region 非泛型 分页信息类
    /// <summary>
    /// 非泛型 分页信息类
    /// </summary>
    [Serializable]
    public class Pagination : IPagination
    {
        protected readonly IEnumerable _collection;

        #region 属性
        /// <summary>
        /// 总记录数
        /// </summary>
        public int TotalRowCount { get; private set; }
        /// <summary>
        /// 起始行索引号（从0开始）
        /// </summary>
        public int StartRowIndex { get; private set; }
        /// <summary>
        /// 页面大小
        /// </summary>
        public int PageSize { get; private set; }
        /// <summary>
        /// 页面索引号（从0开始）
        /// </summary>
        public int PageIndex { get; private set; }
        /// <summary>
        /// 页面编号（从1开始）
        /// </summary>
        public int PageNumber { get { return PageIndex + 1; } private set { PageIndex = value - 1; } }
        /// <summary>
        /// 总页面数 
        /// </summary>
        public int PageCount { get; private set; }
        /// <summary>
        /// 当前页面记录数
        /// </summary>
        public int Length { get; private set; }
        /// <summary>
        /// 是否可以进行分页（分页条件是PageCount > 1)
        /// </summary>
        public bool HasPagination { get; private set; }
        /// <summary>
        /// 是否支持上一页
        /// </summary>
        public bool HasPrevious
        {
            get
            {
                if (!HasPagination || PageCount <= 2) return false;
                return PageIndex != 0 && PageIndex != 1;
            }
        }
        /// <summary>
        /// 是否支持下一页
        /// </summary>
        public bool HasNext { get { return HasPagination && PageIndex < PageCount - 2; } }
        /// <summary>
        /// 是否首页
        /// </summary>
        public bool HasFirst
        {
            get
            {
                //return HasPagination && PageIndex > 0 && PageIndex <= PageCount - 1;
                return HasPagination && PageCount - PageIndex < PageCount;
            }
        }
        /// <summary>
        /// 是否末页
        /// </summary>
        public bool HasLast
        {
            get
            {
                if (!HasPagination)
                    return false;
                //if (PageCount == 2)
                //    return PageIndex == 0;
                //return PageIndex != PageCount - 2 || PageIndex != PageCount - 1;
                return PageCount - PageIndex != 1;
            }
        }

        public int RowCount { get; private set; }

        /// <summary>
        /// 数据
        /// </summary>
        public IEnumerable Data { get; private set; }

        ///// <summary>
        ///// 有分页数据的model
        ///// </summary>
        //public PageinationModel WebData { get {
        //    return new PageinationModel(this);
        //} }
        #endregion

        #region 构造函数
        /// <summary>
        /// IEnumerable类型数据源的构造函数
        /// </summary>
        /// <modelExp name="collection">数据源集合</modelExp>
        /// <modelExp name="pageIndex">页面索引号，下标从1开始</modelExp>
        /// <modelExp name="pageSize">页面大小</modelExp>
        public Pagination(IEnumerable collection, int pageIndex, int pageSize, int rowCount)
        {
            if (pageIndex < 1)
                pageIndex = 1;
                //throw new ArgumentException("页面索引必须大于或等于0至少");
            if (pageSize < 1)
                pageSize = 1;
                //throw new ArgumentException("页面大小不可以小于0");

            _collection = collection;

            PageSize = pageSize;
            PageNumber = pageIndex;  //当前页从1开始
            StartRowIndex = pageIndex * pageSize;
            TotalRowCount = rowCount;   //数据总行数
            PageCount = TotalRowCount / pageSize;   //页面总数
            if (TotalRowCount % pageSize != 0)
                PageCount = PageCount + 1;
            HasPagination = PageCount > 1;  //是否分页

            //_collection = _collection.Skip(StartRowIndex).Take(PageSize).ToArray();

            Length = _collection.Cast<object>().Count();  //当前页总数
        }
        

        /// <summary>
        /// DataTable类型数据源的构造函数
        /// </summary>
        /// <param name="table">DataTable数据集</param>
        /// <param name="pageIndex">当前页 下标从 1 开始</param>
        /// <param name="pageSize">页面大小</param>
        /// <param name="rowCount">总行数</param>
        public Pagination(DataTable table, int pageIndex, int pageSize, int rowCount)
            : this(new DataTableAdapter(table), pageIndex, pageSize, rowCount)
        {

        }
        #endregion

        #region DataTable 适配器
        /// <summary>
        /// DataTable 适配器
        /// </summary>
        class DataTableAdapter : IEnumerable, IListSource
        {
            private DataTable Table;
            private IListSource Target;

            public DataTableAdapter(DataTable table)
            {
                Table = table;
                Target = table as IListSource;
            }
            public IEnumerator GetEnumerator()
            {
                return GetList().GetEnumerator();
            }

            public bool ContainsListCollection
            {
                get { return Target.ContainsListCollection; }
            }

            public IList GetList()
            {
                return Target.GetList();
            }
        }
        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return _collection.GetEnumerator();
        }

        #endregion
    }
    #endregion

    #region 泛型 分页信息类
    /// <summary>
    /// 泛型 分页信息类
    /// </summary>
    [Serializable]
    public class Pagination<T> : Pagination
    {
        private readonly IEnumerable<T> Data;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="collection">数据集合</param>
        /// <param name="pageIndex">当前页 从1开始</param>
        /// <param name="pageSize">当前页大小</param>
        public Pagination(IEnumerable<T> collection, int pageIndex, int pageSize) : this(collection.Skip((pageIndex-1) * pageSize).Take(pageSize).ToArray(), pageIndex, pageSize, collection.Count()) { }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <modelExp name="collection">数据源集合</modelExp>
        /// <modelExp name="pageIndex">页面索引号，下标从1开始</modelExp>
        /// <modelExp name="pageSize">页面大小</modelExp>
        public Pagination(IEnumerable<T> collection, int pageIndex, int pageSize, int rowCount)
            : base(collection, pageIndex, pageSize, rowCount)
        {
            Data = collection;
        }

        #region IEnumerable<T> Members

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public IEnumerator<T> GetEnumerator()
        {
            return Data.GetEnumerator();
        }

        #endregion

        /// <summary>
        /// 空记录集对象
        /// </summary>
        public static readonly Pagination<T> Empty = new Pagination<T>(Enumerable.Empty<T>(), 0, 10, 0);
    }
    #endregion
}
